package com.example.guli.service.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.guli.common.base.result.R;
import com.example.guli.service.edu.entity.*;
import com.example.guli.service.edu.entity.vo.*;
import com.example.guli.service.edu.mapper.*;
import com.example.guli.service.base.DTO.CourseDto;

import com.example.guli.service.edu.entity.form.CourseInfoForm;
import com.example.guli.service.edu.feign.OssFileService;

import com.example.guli.service.edu.service.CourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author shunxuan
 * @since 2020-07-16
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {
    //注意：为了避免idea在这个位置报告找不到依赖的错误，
    // 我们可以在CourseDescriptionMapper接口上添加@Repository注解
    @Autowired//注入依赖，课程简介，即数据库分表的字段
    private CourseDescriptionMapper courseDescriptionMapper;

    @Autowired
    private OssFileService ossFileService;

    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private ChapterMapper chapterMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private CourseCollectMapper courseCollectMapper;
    @Autowired
    private TeacherMapper teacherMapper;



    @Transactional(rollbackFor = Exception.class)//错误回滚

    @Override
    public String saveCourseInfo(CourseInfoForm courseInfoForm) {
//        保存course 课程基本信息
        Course course=new Course();
//        方法一、一个一个保存
//        course.setTitle(courseInfoForm.getTitle());
//        方法二、使用BeanUtils方法即可
//        courseInfoForm中的属性名要和course中的属性名一样，否则无法拷贝
        /**
         * 对象属性拷贝
         * @param source 源对象
         * @param target 目标对象
         * 将源对象的属性拷贝到目标对象
        */
        BeanUtils.copyProperties(courseInfoForm,course);
        course.setStatus(Course.COURSE_DRAFT);//修改状态，草稿
        baseMapper.insert(course);

//        保存coursedescription 课程详情信息
        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setDescription(courseInfoForm.getDescription());
        //Course表有了分布式主键策略，CourseDescription就不应该有自己的策略，而是应该和Course表的主键策略保持一致
        //之前取消了CourseDescription的主键策略，现在需要设置主键，即id
        courseDescription.setId(course.getId());
        //不能使用baseMapper了，因为baseMapper只对当前的实现类生效，所以需要注入courseDescriptionMapper来进行保存
        courseDescriptionMapper.insert(courseDescription);
        return course.getId();
    }

    @Override
    public void updateCourseInfoById(CourseInfoForm courseInfoForm) {
        //更新课程基本信息
        Course course = new Course();
        BeanUtils.copyProperties(courseInfoForm, course);
        baseMapper.updateById(course);

        //更新课程详情信息
        CourseDescription courseDescription = new CourseDescription();
        courseDescription.setDescription(courseInfoForm.getDescription());
        courseDescription.setId(course.getId());
        courseDescriptionMapper.updateById(courseDescription);
    }

    @Override
    public CourseInfoForm getCourseInfoById(String id) {
//        根据id获取course
        Course course = baseMapper.selectById(id);
        if(course==null){
            return null;
        }
//        根据id获取coursedescription
        CourseDescription courseDescription = courseDescriptionMapper.selectById(id);

//        组装成courseInfoForm
        CourseInfoForm courseInfoForm = new CourseInfoForm();
        //将course拷贝到courseInfoForm
        BeanUtils.copyProperties(course,courseInfoForm);
        //拷贝之后没有description，需要将查到的coursedescription表中的description字段设置过去
        courseInfoForm.setDescription(courseDescription.getDescription());

        return courseInfoForm;

    }

    //实现多表联查
    @Override
    public IPage<CourseVo> selectPage(Long page, Long limit, CourseQueryVo courseQueryVo) {
        QueryWrapper<CourseVo> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("c.gmt_create");

        String title = courseQueryVo.getTitle();
        String teacherId = courseQueryVo.getTeacherId();
        String subjectParentId = courseQueryVo.getSubjectParentId();
        String subjectId = courseQueryVo.getSubjectId();

        if (!StringUtils.isEmpty(title)) {
            queryWrapper.like("c.title", title);
        }

        if (!StringUtils.isEmpty(teacherId) ) {
            queryWrapper.eq("c.teacher_id", teacherId);
        }

        if (!StringUtils.isEmpty(subjectParentId)) {
            queryWrapper.eq("c.subject_parent_id", subjectParentId);
        }

        if (!StringUtils.isEmpty(subjectId)) {
            queryWrapper.eq("c.subject_id", subjectId);
        }

        Page<CourseVo> pageParam = new Page<>(page, limit);
        //放入分页参数和查询条件参数，mp会自动组装
        List<CourseVo> records = baseMapper.selectPageByCourseQueryVo(pageParam, queryWrapper);
        pageParam.setRecords(records);
        return pageParam;

    }

    @Override
    public boolean removeCoverById(String id) {
        //根据id获取讲师avatar 的 url
        Course course = baseMapper.selectById(id);
        if(course!=null){
            String cover = course.getCover();
            System.out.println(cover);
            if(!StringUtils.isEmpty(cover)){
//                根据oss删除图片
                R r=ossFileService.removeFile(cover);
                return r.getSuccess();
            }
        }
        return false;
    }

    /**
     * 数据库中外键约束的设置：
     *   互联网分布式项目中不允许使用外键与级联更新，一切设计级联的操作不要依赖数据库层，要在业务层解决
     *
     * 如果业务层解决级联删除功能
     *   那么先删除子表数据，再删除父表数据

     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeCourseById(String id) {
        //根据courseId删除Video(课时)
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.eq("course_id",id);
        videoMapper.delete(videoQueryWrapper);

        //根据courseId删除Chapter(章节)
        QueryWrapper<Chapter> chapterQueryWrapper = new QueryWrapper<>();
        chapterQueryWrapper.eq("course_id",id);
        chapterMapper.delete(chapterQueryWrapper);

        //根据courseId删除Comment(评论)
        QueryWrapper<Comment> commentQueryWrapper = new QueryWrapper<>();
        commentQueryWrapper.eq("course_id",id);
        commentMapper.delete(commentQueryWrapper);

        //根据courseId删除CourseCollect(课程收藏)
        QueryWrapper<CourseCollect> courseCollectQueryWrapper = new QueryWrapper<>();
        courseCollectQueryWrapper.eq("course_id",id);
        courseCollectMapper.delete(courseCollectQueryWrapper);

        //根据courseId删除CourseDescription(课程详情)
        courseDescriptionMapper.deleteById(id);

        //删除课程
        return this.removeById(id);
    }

    @Override
    public CoursePublishVo getCoursePublishVoById(String id) {
        return baseMapper.selectCoursePublishVoById(id);
    }

    @Override
    public boolean publishCourseById(String id) {
        Course course = new Course();
        course.setId(id);
        course.setStatus(Course.COURSE_NORMAL);
        System.out.println(this);
        return this.updateById(course);
    }

    @Override
    public List<Course> webSelectList(WebCourseQueryVo webCourseQueryVo) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //查询已发布的课程
        queryWrapper.eq("status",Course.COURSE_NORMAL);
        //条件查询
        String subjectParentId = webCourseQueryVo.getSubjectParentId();
        String subjectId = webCourseQueryVo.getSubjectId();
        String buyCountSort = webCourseQueryVo.getBuyCountSort();
        String gmtCreateSort = webCourseQueryVo.getGmtCreateSort();
        String priceSort = webCourseQueryVo.getPriceSort();
        if(!StringUtils.isEmpty(subjectParentId)){
            queryWrapper.eq("subject_parent_id",subjectParentId);
        }
        if(!StringUtils.isEmpty(subjectId)){
            queryWrapper.eq("subject_id",subjectId);
        }
        if(!StringUtils.isEmpty(buyCountSort)){
            queryWrapper.orderByDesc("buy_count");
        }
        if(!StringUtils.isEmpty(gmtCreateSort)){
            queryWrapper.orderByDesc("gmt_create");
        }
        if(!StringUtils.isEmpty(priceSort)){
            queryWrapper.orderByDesc("price");
        }
        return baseMapper.selectList(queryWrapper);

    }

    @Override
    public List<Course> selectHotCourse() {
        QueryWrapper<Course> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.orderByDesc("view_count");
        courseQueryWrapper.last("limit 8");
        return baseMapper.selectList(courseQueryWrapper);
    }

    @Override
    public CourseDto getCourseDtoById(String courseId) {
//       方法一：一条sql
       return baseMapper.selectCourseDtoById(courseId);

//        方法二：两条sql
//        Course course = baseMapper.selectById(courseId);

//        String teacherId = course.getTeacherId();
//        Teacher teacher = teacherMapper.selectById(teacherId);
//
//        CourseDto courseDto = new CourseDto();
//        courseDto.setId(course.getId());
//        courseDto.setCover(course.getCover());
//        courseDto.setPrice(course.getPrice());
//        courseDto.setTitle(course.getTitle());
//        courseDto.setTeacherName(teacher.getName());
//        return CourseDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public WebCourseVo selectWebCourseVoById(String courseId) {
//        更新课程浏览数
        Course course = baseMapper.selectById(courseId);
        course.setViewCount(course.getViewCount()+1);
        baseMapper.updateById(course);
//        获取课程信息和讲师信息
        return baseMapper.selectWebCourseVoById(courseId);
    }

    @Override
    public IPage<Course> webSelectPage(Page<Course> pageParam, WebCourseQueryVo webCourseQueryVo) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        //查询已发布的课程
        queryWrapper.eq("status",Course.COURSE_NORMAL);
        if(webCourseQueryVo == null){
            return baseMapper.selectPage(pageParam,queryWrapper);
        }
        //条件查询
        String subjectParentId = webCourseQueryVo.getSubjectParentId();
        String subjectId = webCourseQueryVo.getSubjectId();
        String buyCountSort = webCourseQueryVo.getBuyCountSort();
        String gmtCreateSort = webCourseQueryVo.getGmtCreateSort();
        String priceSort = webCourseQueryVo.getPriceSort();
        String title = webCourseQueryVo.getTitle();
        if(!StringUtils.isEmpty(subjectParentId)){
            queryWrapper.eq("subject_parent_id",subjectParentId);
       }
        if(!StringUtils.isEmpty(subjectId)){
            queryWrapper.eq("subject_id",subjectId);
        }
        if(!StringUtils.isEmpty(buyCountSort)){
            queryWrapper.eq("buy_count",buyCountSort);
        }
        if(!StringUtils.isEmpty(gmtCreateSort)){
            queryWrapper.eq("gmt_create",gmtCreateSort);
        }
        if(!StringUtils.isEmpty(priceSort)){
            queryWrapper.eq("price",priceSort);
        }
        //模糊查询
        if(!StringUtils.isEmpty(title)){
            queryWrapper.likeRight("title",title);
        }
        return baseMapper.selectPage(pageParam,queryWrapper);

    }

}
